#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QHostInfo>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    LabSocketState = new QLabel("Socket状态：");
    LabSocketState->setMinimumWidth(200);
    ui->statusBar->addWidget(LabSocketState);
    QString localIP = getLocalIP();
    this->setWindowTitle(this->windowTitle()+"----本机IP："+localIP);
    ui->comboTargetIP->addItem(localIP);

    udpSocket = new QUdpSocket(this);
    connect(udpSocket,SIGNAL(stateChanged(QAbstractSocket::SocketState)),this,SLOT(onSocketStateChange(QAbstractSocket::SocketState)));
    onSocketStateChange(udpSocket->state());
    connect(udpSocket,SIGNAL(readyRead()),this,SLOT(onSocketReadyRead()));
}

MainWindow::~MainWindow()
{
    delete ui;
}
QString MainWindow::getLocalIP()
{
    //获取本机IPv4地址
    QString hostName = QHostInfo::localHostName();
    QHostInfo hostInfo = QHostInfo::fromName(hostName);
    QString localIP = "";
    QList<QHostAddress> addList = hostInfo.addresses();

    if(!addList.isEmpty())
    {
        for(int i=0;i<addList.count();i++){
            QHostAddress aHost = addList.at(i);
            if(QAbstractSocket::IPv4Protocol == aHost.protocol()){
                localIP = aHost.toString();
                break;
            }
        }
    }

    return localIP;
}

void MainWindow::on_actStart_triggered()
{
    //绑定端口槽函数
    quint16 port = quint16 (ui->spinBindPort->value());       //本机udp端口
    if(udpSocket->bind(port))       //绑定端口
    {
        ui->plainTextEdit->appendPlainText("**已成功绑定");
        ui->plainTextEdit->appendPlainText("**绑定端口："+QString::number(udpSocket->localPort()));
        ui->actStart->setEnabled(false);
        ui->actStop->setEnabled(true);
    }
    else {
        ui->plainTextEdit->appendPlainText("**绑定失败");
    }
}

void MainWindow::on_actStop_triggered()
{
    //解除绑定槽函数
    udpSocket->abort();     //解除绑定
    ui->actStart->setEnabled(true);
    ui->actStop->setEnabled(false);
    ui->plainTextEdit->appendPlainText("**已解除绑定");
}

void MainWindow::onSocketStateChange(QAbstractSocket::SocketState socketState){
    //socket状态变化时
    switch (socketState) {
    case QAbstractSocket::UnconnectedState:
        LabSocketState->setText("scoket状态：UnconnectedState");
        break;
    case QAbstractSocket::HostLookupState:
        LabSocketState->setText("scoket状态：HostLookupState");
        break;
    case QAbstractSocket::ConnectingState:
        LabSocketState->setText("scoket状态：ConnectingState");
        break;
    case QAbstractSocket::ConnectedState:
        LabSocketState->setText("scoket状态：ConnectedState");
        break;
    case QAbstractSocket::BoundState:
        LabSocketState->setText("scoket状态：BoundState");
        break;
    case QAbstractSocket::ClosingState:
        LabSocketState->setText("scoket状态：ClosingState");
        break;
    case QAbstractSocket::ListeningState:
        LabSocketState->setText("scoket状态：ListeningState");
        break;
    }
}

void MainWindow::on_btnSend_clicked()
{
    QString targetIP = ui->comboTargetIP->currentText();
    QHostAddress targetAddr(targetIP);
    quint16 targetPort = quint16 (ui->spinTargetPort->value());
    QString msg = ui->editMsg->text();
    QByteArray str = msg.toUtf8();
    udpSocket->writeDatagram(str,targetAddr,targetPort);        //写入数据,广播消息时地址为QHostAddress::Broadcast,255.255.255.255
    ui->plainTextEdit->appendPlainText("[out] "+msg);
    ui->editMsg->clear();
    ui->editMsg->setFocus();
}

void MainWindow::onSocketReadyRead()
{   //是否有待读取的数据
    while (udpSocket->hasPendingDatagrams()) {
        QByteArray datagram;
        datagram.resize(udpSocket->pendingDatagramSize());  //待读取数据报的字节数
        QHostAddress peerAddr;
        quint16 peerPort;
        udpSocket->readDatagram(datagram.data(),datagram.size(),&peerAddr,&peerPort);
        QString str = datagram.data();
        QString peer = "[From "+peerAddr.toString()+":"+QString::number(peerPort)+"] ";
        ui->plainTextEdit->appendPlainText(peer+str);
    }
}

void MainWindow::on_btnBroadcast_clicked()
{
    QString targetIP = ui->comboTargetIP->currentText();
    QHostAddress targetAddr(targetIP);
    quint16 targetPort = quint16 (ui->spinTargetPort->value());
    QString msg = ui->editMsg->text();
    QByteArray str = msg.toUtf8();
    udpSocket->writeDatagram(str,QHostAddress::Broadcast,targetPort);        //写入数据,广播消息时地址为QHostAddress::Broadcast,255.255.255.255
    ui->plainTextEdit->appendPlainText("[out] "+msg);
    ui->editMsg->clear();
    ui->editMsg->setFocus();

}

void MainWindow::on_pushButton_clicked()
{
    QHostAddress host(getLocalIP());
    udpSocket->joinMulticastGroup(host);
}
